package com.yami.shop.platform.task;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.yami.shop.bean.enums.SceneType;
import com.yami.shop.bean.enums.TradeType;
import com.yami.shop.bean.event.AssetTrendsEvent;
import com.yami.shop.bean.event.UpdateRightsEvent;
import com.yami.shop.bean.model.*;
import com.yami.shop.bean.vo.AssetTrendsVO;
import com.yami.shop.common.config.Constant;
import com.yami.shop.common.exception.YamiShopBindException;
import com.yami.shop.common.util.DataWebService;
import com.yami.shop.common.util.RedisUtil;
import com.yami.shop.config.ShopConfig;
import com.yami.shop.dao.RedPacketInfoMapper;
import com.yami.shop.personnft.common.dao.PersonNftAccountMapper;
import com.yami.shop.personnft.common.dao.PersonNftApplyMapper;
import com.yami.shop.personnft.common.model.PersonNft;
import com.yami.shop.personnft.common.model.PersonNftAccount;
import com.yami.shop.personnft.common.service.PersonNftService;
import com.yami.shop.service.*;
import com.yami.shop.user.common.model.UserGasLog;
import com.yami.shop.user.common.service.UserBalanceService;
import com.yami.shop.user.common.service.UserGasInfoService;
import com.yami.shop.user.common.service.UserGasLogService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

import static com.yami.shop.util.RedPacketUtils.*;

@Component
public class RedPacketTask {

    private Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private ChannelUserRelationRecordService channelUserRelationRecordService;
    @Autowired
    private UserGasLogService userGasLogService;
    @Autowired
    private ShopConfig shopConfig;
    @Autowired
    private DataWebService dataWebService;
    @Autowired
    private UserBalanceService userBalanceService;
    @Autowired
    private RedPacketInfoMapper redPacketInfoMapper;
    @Autowired
    private RedPacketInfoService redPacketInfoService;
    @Autowired
    private RedPacketRecordService redPacketRecordService;
    @Autowired
    private UserService userService;
    @Autowired
    private PersonNftService personNftService;
    @Autowired
    private PersonNftApplyMapper personNftApplyMapper;
    @Autowired
    private PersonNftAccountMapper personNftAccountMapper;
    @Autowired
    private UserGasInfoService userGasInfoService;
    @Autowired
    private ApplicationContext applicationContext;
    @Autowired
    private RedTokenRecordService redTokenRecordService;
    @Autowired
    private ProductService productService;

    /**
     * 红包到期定时任务
     */
    @XxlJob("redPacketTask")
    public void redPacketTask() {
        logger.info("1分钟 ================红包过期定时任务=====================");
        {
            // 获取过期的红包
            List<RedPacketInfo> hours = redPacketInfoMapper.getHours();
            for (RedPacketInfo redPacketInfo : hours) {
                // 删除Redis 缓存
                String redPackageKey = RED_PACKAGE_KEY + redPacketInfo.getId();
                String grabRedPackageKey = GRAB_RED_PACKAGE_KEY + redPacketInfo.getId();
                String redPackageConsumeKey = RED_PACKAGE_CONSUME_KEY + redPacketInfo.getId();
                RedisUtil.del(redPackageKey, grabRedPackageKey, redPackageConsumeKey);
                // 添加退款记录
                // 记录本次拆红包
                if (redPacketInfo.getRemainingAmount() > 0 && redPacketInfo.getRemainingPacket() > 0) {
                    RedPacketRecord redPacketRecord = RedPacketRecord.builder()
                            .redPacketId(redPacketInfo.getId())
                            .amount(redPacketInfo.getRemainingAmount())
//                        .createTime(LocalDateTime.now())
                            .userId(redPacketInfo.getUserId())
                            .type(redPacketInfo.getType())
                            .recType(2)
                            .build();
                    redPacketRecordService.save(redPacketRecord);
                }
                redPacketInfo.setStatus(2);
            }
            // 修改红包状态
            redPacketInfoService.updateBatchById(hours);
        }
    }

    /**
     * 定时任务处理红包抽取记录
     */
    @XxlJob("redPacketRecordTask")
    public void redPacketRecordTask() {
        logger.info("30秒 ================红包抽取记录定时任务=====================");
        // 获取待处理红包领取记录
        QueryWrapper<RedPacketRecord> redPacketRecordQueryWrapper = new QueryWrapper<>();
        redPacketRecordQueryWrapper.eq("status", 0);
        List<RedPacketRecord> redPacketRecordList = redPacketRecordService.list(redPacketRecordQueryWrapper);
        redPacketRecordList.forEach(redPacketRecord -> {
            RedPacketInfo byId = redPacketInfoService.getById(redPacketRecord.getRedPacketId());
            // 获取红包记录总和
            QueryWrapper<RedPacketRecord> queryWrapper = new QueryWrapper();
            queryWrapper.eq("red_packet_id", redPacketRecord.getRedPacketId());
            List<RedPacketRecord> list = redPacketRecordService.list(queryWrapper);
            double sumNum = list.stream().mapToDouble(RedPacketRecord::getAmount).sum();
            if (sumNum > byId.getTotalAmount()) {
                logger.error("红包总额错误");
                redPacketRecord.setStatus(2);
                redPacketRecordService.updateById(redPacketRecord);
                throw new YamiShopBindException("红包总额错误");
            }
            switch (redPacketRecord.getType()) {
                // 人民币红包 ---------  调用支付接口
                case "0":
                    logger.info("人民币定时任务");
                    // 获取新生user_id
                    User userDetail = userService.getUserDetail(byId.getUserId());
                    try {
                        userBalanceService.receiveRedPacketSaveUserBalanceData(userDetail.getXsUserId(), userDetail.getUserId(),
                                redPacketRecord.getXsUserId(), redPacketRecord.getUserId(),
                                redPacketRecord.getAmount(),
                                redPacketRecord.getRecType() + "",
                                redPacketRecord.getRedPacketId(),
                                redPacketRecord.getId());
                        // 修改数据
                        redPacketRecord.setStatus(1);
                        redPacketRecordService.updateById(redPacketRecord);
                    } catch (Exception e) {
                        logger.info("人民币定时任务错误" + e);
                        redPacketRecord.setStatus(2);
                        redPacketRecordService.updateById(redPacketRecord);
                    }
                    break;
                // NFT红包 ----------- 调用转增接口
                case "1":
                    redPacketRecord.setStatus(1);
                    String tokens = "";
                    try {
                        // 获取token
                        tokens = getTokenByDtc(byId, redPacketRecord);
                        logger.info("获取到的token{}", tokens);
                    } catch (Exception e) {
                        logger.error("红包领取定时任务异常{}", e);
                        redPacketRecord.setStatus(2);
                        redPacketRecordService.updateById(redPacketRecord);
                        break;
                    }
                    // 如果是领取调用转增接口
                    if (redPacketRecord.getRecType() == 1) {
                        // typr 1 为 DTC 2 为 外部导入
                        if ("1".equals(byId.getChainType())) {
                            // DTC 红包 转赠
                            try {
                                redPacketDrawPersonnft(tokens, redPacketRecord.getUserId(), redPacketRecord.getRedPacketId());
                            } catch (Exception e) {
                                redPacketRecord.setStatus(2);
                                logger.error("红包定时任务---DTC红包转赠异常{}", e);
                            }
                        } else if ("2".equals(byId.getChainType())) {
                            // 获取接收人下游userId
                            try {
                                ChannelUserRelationRecord toUser = channelUserRelationRecordService.getOne(new QueryWrapper<ChannelUserRelationRecord>()
                                        .lambda()
                                        .eq(ChannelUserRelationRecord::getUserId, redPacketRecord.getUserId())
                                        .eq(ChannelUserRelationRecord::getStatus, 0)
                                        .eq(ChannelUserRelationRecord::getChannelCode, byId.getChannelCode())
                                        .eq(ChannelUserRelationRecord::getChainCode, byId.getChainCode())
                                        .eq(ChannelUserRelationRecord::getType, byId.getChainType())
                                        .last("limit 1"));

                                // 获取发送人下游userId
                                ChannelUserRelationRecord formUser = channelUserRelationRecordService.getOne(new QueryWrapper<ChannelUserRelationRecord>()
                                        .lambda()
                                        .eq(ChannelUserRelationRecord::getUserId, byId.getUserId())
                                        .eq(ChannelUserRelationRecord::getStatus, 0)
                                        .eq(ChannelUserRelationRecord::getChannelCode, byId.getChannelCode())
                                        .eq(ChannelUserRelationRecord::getChainCode, byId.getChainCode())
                                        .eq(ChannelUserRelationRecord::getType, byId.getChainType())
                                        .last("limit 1"));
                                // 获取applyId 以及 prodCode denomId
                                QueryWrapper<RedTokenRecord> redTokenRecordQueryWrapper = new QueryWrapper<>();
                                redTokenRecordQueryWrapper.eq("red_id", byId.getId());
                                redTokenRecordQueryWrapper.in("tokens_id", Arrays.asList(tokens.split(",")));
                                List<RedTokenRecord> list1 = redTokenRecordService.list(redTokenRecordQueryWrapper);
                                Map<String, String> stringObjectMap1 = new HashMap<>();
                                stringObjectMap1.put("tokenIds", tokens);
                                stringObjectMap1.put("formUserId", formUser.getChannelUserId());
                                stringObjectMap1.put("toUserId", toUser.getChannelUserId());
                                stringObjectMap1.put("type", "1");
                                stringObjectMap1.put("channelCode", byId.getChannelCode());
                                stringObjectMap1.put("id", list1.get(0).getApplyId());
                                String url1 = shopConfig.getApiGatewayUrl() + "/personnft/outapi/app/personnftApply/transferPerson?";
//                        String url1 = "http://localhost:9206/outapi/app/personnftApply/redPacketDrawPersonnft?";
                                JSONObject jsonObject1 = new JSONObject();
                                jsonObject1 = dataWebService.hutoolPostWebService(url1, stringObjectMap1, null, null);
                                if (null == jsonObject1 || jsonObject1.getInteger("code") != Constant.SUCCESS_CODE) {
                                    throw new YamiShopBindException(jsonObject1.getString("msg"));
                                }
                                //2增加受赠方藏品记录
                                PersonNftAccount personNftAccount = PersonNftAccount.builder()
                                        .sceneType(Integer.valueOf(SceneType.RedAdd.getCode()))
                                        .content(tokens)
                                        .dawProductCode(list1.stream().map(RedTokenRecord::getProductCode).collect(Collectors.joining(",")))
                                        .channelType(byId.getChainType())
                                        .denomId(list1.get(0).getDenomId())
                                        .userId(redPacketRecord.getUserId())
                                        .createTime(DateUtil.date())
                                        .id(cn.hutool.core.util.IdUtil.getSnowflake().nextIdStr())
                                        .count(redPacketRecord.getAmount().intValue())
                                        .productId(byId.getProdId())
                                        .channelCode(byId.getChannelCode())
                                        .chainCode(byId.getChainCode())
                                        .type(1)
                                        .orderId(redPacketRecord.getId().toString())
                                        .build();
                                personNftAccountMapper.save(personNftAccount);
                                //5 转增方转增记录
                                PersonNftAccount personNftAccount1 = PersonNftAccount.builder()
                                        .sceneType(Integer.valueOf(SceneType.RedTransfer.getCode()))
                                        .content(tokens)
                                        .dawProductCode(list1.stream().map(RedTokenRecord::getProductCode).collect(Collectors.joining(",")))
                                        .channelType(byId.getChainType())
                                        .denomId(list1.get(0).getDenomId())
                                        .userId(byId.getUserId())
                                        .createTime(DateUtil.date())
                                        .id(IdUtil.getSnowflake().nextIdStr())
                                        .count(redPacketRecord.getAmount().intValue())
                                        .productId(byId.getProdId())
                                        .channelCode(byId.getChannelCode())
                                        .type(1)
                                        .chainCode(byId.getChainCode())
                                        .orderId(redPacketRecord.getId().toString())
                                        .build();
                                personNftAccountMapper.save(personNftAccount1);
                            } catch (Exception e) {
                                redPacketRecord.setStatus(2);
                            }
                        }
                    }
                    // 如果是领取调用解冻接口
                    else if (redPacketRecord.getRecType() == 2 || redPacketRecord.getRecType() == 3) {
                        // typr 1 为 DTC 2 为 外部导入
                        if ("1".equals(byId.getChainType())) {
                            logger.info("退回解冻{}", tokens);
                            try {
                                unfreezePersonnft(redPacketRecord.getUserId(), redPacketRecord.getAmount().intValue(), redPacketRecord.getRedPacketId(), tokens);
                            } catch (Exception e) {
                                redPacketRecord.setStatus(2);
                                logger.error("红包定时任务---退回解冻异常{}", e);
                            }
                        } else if ("2".equals(byId.getChainType())) {
                            // 获取下游UserId
                            ChannelUserRelationRecord channelUserRelationRecord = channelUserRelationRecordService.getOne(new QueryWrapper<ChannelUserRelationRecord>()
                                    .lambda()
                                    .eq(ChannelUserRelationRecord::getUserId, redPacketRecord.getUserId())
                                    .eq(ChannelUserRelationRecord::getStatus, 0)
                                    .eq(ChannelUserRelationRecord::getChannelCode, byId.getChannelCode())
                                    .eq(ChannelUserRelationRecord::getChainCode, byId.getChainCode())
                                    .eq(ChannelUserRelationRecord::getType, byId.getChainType())
                                    .last("limit 1"));
                            // 获取下游商品ID
                            Product product = productService.getOne(Wrappers.lambdaQuery(Product.class).eq(Product::getProdId, byId.getProdId()).eq(Product::getSource, "1"));
                            // 获取applyId
                            QueryWrapper<RedTokenRecord> redTokenRecordQueryWrapper = new QueryWrapper<>();
                            redTokenRecordQueryWrapper.eq("tokens_id", Arrays.asList(tokens.split(",")).get(0));
                            redTokenRecordQueryWrapper.eq("red_id", byId.getId());
                            redPacketRecordQueryWrapper.last("limit 1");
                            RedTokenRecord one = redTokenRecordService.getOne(redTokenRecordQueryWrapper);
                            Map<String, String> stringObjectMap1 = new HashMap<>();
                            stringObjectMap1.put("tokenIds", tokens);
                            stringObjectMap1.put("userId", channelUserRelationRecord.getChannelUserId());
                            stringObjectMap1.put("productId", product.getSourceId().toString());
                            stringObjectMap1.put("channelCode", byId.getChannelCode());
                            stringObjectMap1.put("status", "0");
                            stringObjectMap1.put("id", one.getApplyId());
                            // 发布测试修改
                            String url2 = shopConfig.getApiGatewayUrl() + "/personnft/outapi/app/personnftApply/unFreeze?";
//                        String url2 = "http://localhost:9206/outapi/app/personnftApply/freezePersonnft?";
                            JSONObject jsonObject2 = new JSONObject();
                            try {
                                jsonObject2 = dataWebService.hutoolPostWebService(url2, stringObjectMap1, null, null);
                                if (null == jsonObject2 || jsonObject2.getInteger("code") != Constant.SUCCESS_CODE) {
                                    throw new YamiShopBindException(jsonObject2.getString("msg"));
                                }
                            } catch (Exception e) {
                                redPacketRecord.setStatus(2);
                            }
                        }
                        // 红包退回Gas新增 退回记录
                        if (redPacketRecord.getRecType() == 2 && redPacketRecord.getStatus() == 1) {
                            // 添加 gas
                            userGasInfoService.saveGasNumberByUserId(redPacketRecord.getUserId(), redPacketRecord.getAmount().intValue());
                            // 添加记录
                            UserGasLog userGasLog = new UserGasLog();
                            userGasLog.setCreateTime(new Date());
                            userGasLog.setIoType(2); // 收支类型 0支出 1收入
                            userGasLog.setType(5);   // gas记录 类型
                            userGasLog.setIsPayed(1);  // 0未支付
                            userGasLog.setPayNo(redPacketRecord.getRedPacketId().toString());  // 支付单号
                            userGasLog.setUserId(redPacketRecord.getUserId());
                            userGasLog.setGasId(redPacketRecord.getId());
                            userGasLog.setTabStatus(1); //已处理--- 已发送
                            userGasLog.setPateTab(byId.getChannelCode());  //平台
                            userGasLog.setGasNum(redPacketRecord.getAmount().intValue());
                            userGasLogService.save(userGasLog);
                        }
                    }
                    // 保存数据
                    redPacketRecord.setTokenId(tokens);
                    // 如果修改失败 取的token回退
                    if (redPacketRecord.getStatus() == 2) {
                        LambdaUpdateWrapper<RedTokenRecord> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
                        lambdaUpdateWrapper.eq(RedTokenRecord::getRedId, byId.getId());
                        lambdaUpdateWrapper.in(RedTokenRecord::getTokensId, Arrays.asList(tokens.split(",")));
                        lambdaUpdateWrapper.set(RedTokenRecord::getStatus, "0");
                        redTokenRecordService.update(lambdaUpdateWrapper);
                    }
                    redPacketRecordService.updateById(redPacketRecord);
                    break;
                case "2":
                    // Gas红包 ----------- 调用gas增加接口
                    try {
                        // 添加Gas
                        userGasInfoService.saveGasNumberByUserId(redPacketRecord.getUserId(), redPacketRecord.getAmount().intValue());

                        // DTC++ 添加Gas记录
                        UserGasLog userGasLog = new UserGasLog();
                        userGasLog.setCreateTime(new Date());
                        userGasLog.setUserId(redPacketRecord.getUserId());
                        userGasLog.setIoType(redPacketRecord.getRecType() == 2 ? 2 : 1); // 收支类型 0支出 1收入
                        userGasLog.setType(4);   // gas 记录类型
                        userGasLog.setIsPayed(1);  // 0未支付
                        userGasLog.setPayNo(redPacketRecord.getId().toString());  // 支付单号
                        userGasLog.setToUserId(byId.getUserId()); // 发红包用户id
                        userGasLog.setGasId(byId.getId());
                        userGasLog.setTabStatus(1); //已处理--- 已发送
                        userGasLog.setGasNum(redPacketRecord.getAmount().intValue());
                        userGasLogService.save(userGasLog);

                        // 修改数据
                        redPacketRecord.setStatus(1);
                        redPacketRecord.setGasNum(redPacketRecord.getAmount().intValue());
                        redPacketRecordService.updateById(redPacketRecord);
                    } catch (Exception e) {
                        logger.error("gas红包发送异常{}", e);
                        redPacketRecord.setStatus(2);
                        redPacketRecordService.updateById(redPacketRecord);
                    }
                    break;
            }
        });
    }

    private void unfreezePersonnft(String userId, Integer tokenNum, Long redPacketId, String tokenIds) {
        {
            // 查询对应持仓个数
            PersonNft personNft = PersonNft.builder().status(1).userId(userId).build();
            PersonNftApply personNftApply = personNftApplyMapper.selectByRedIdAndUserId(redPacketId, userId, "");
            personNft.setDenomId(personNftApply.getDenomId());
            personNft.setTokenIds(Arrays.asList(tokenIds.split(",")));
            List<PersonNft> personNfts = personNftService.listByParam(personNft);
            if (personNfts.size() < tokenNum) {
                throw new YamiShopBindException("持仓状态异常");
            }
            // 添加账单表
            List<PersonNft> freezePerson = personNfts.subList(0, tokenNum);
            String contenStr = String.join(",", freezePerson.stream().map(s -> s.getTokenId()).collect(Collectors.toList()));
            String dawProductCode = String.join(",", freezePerson.stream().map(s -> s.getDawProductCode()).collect(Collectors.toList()));

            // 自己领取自己红包 / 红包退回 -- 解冻过程
            PersonNftAccount personNftAccount = PersonNftAccount.builder()
                    .sceneType(Integer.valueOf(SceneType.RedAdd.getCode()))
                    .content(contenStr)
                    .dawProductCode(dawProductCode)
//                .dawNameId(freezePerson.get(0).getDawNameId())
                    .denomId(freezePerson.get(0).getDenomId())
                    .userId(userId)
                    .createTime(DateUtil.date())
                    .id(IdUtil.getSnowflake().nextIdStr())
                    .channelType(personNftApply.getChannelType())
                    .chainCode(personNftApply.getChainCode())
                    .channelCode(personNftApply.getChannelCode())
                    .count(tokenNum)
                    .productId(freezePerson.get(0).getProductId())
                    .orderId(redPacketId + "")
                    .build();
            personNftAccountMapper.save(personNftAccount);
            //5 转增方转增记录
            PersonNftAccount personNftAccount1 = PersonNftAccount.builder()
                    .sceneType(Integer.valueOf(SceneType.RedTransfer.getCode()))
                    .content(contenStr)
                    .dawProductCode(dawProductCode)
//                    .dawNameId(freezePerson.get(0).getDawNameId())
                    .denomId(freezePerson.get(0).getDenomId())
                    .userId(userId)
                    .createTime(DateUtil.date())
                    .id(IdUtil.getSnowflake().nextIdStr())
                    .channelType(personNftApply.getChannelType())
                    .chainCode(personNftApply.getChainCode())
                    .channelCode(personNftApply.getChannelCode())
                    .count(tokenNum)
                    .productId(freezePerson.get(0).getProductId())
                    .orderId(redPacketId + "")
                    .build();
            personNftAccountMapper.save(personNftAccount1);
            // 冻结持仓
            freezePerson.stream().forEach(s -> s.setStatus(0));
            personNftService.updateBatch(freezePerson);
        }
    }

    private void redPacketDrawPersonnft(String tokenIds, String userId, Long redPacketId) {
        logger.info("获取Token{}", tokenIds);
        PersonNftApply personNftApply = personNftApplyMapper.selectByRedIdAndUserId(redPacketId, "", "");
        List<PersonNft> lsitAdd = new ArrayList<>();
        List<PersonNft> lsit = new ArrayList<>();
        List<String> tokenList = Arrays.asList(tokenIds.split(","));
        List<String> prodCode = new ArrayList<>();
        for (String tokenId : tokenList) {
            //1增加受赠方持仓
            PersonNft personNft = PersonNft.builder().tokenId(tokenId).status(4).build();
            List<PersonNft> personNfts = personNftService.listByParam(personNft);
            //校验受赠方是否有该未删除的tokenid
            List<PersonNft> list = personNfts.stream().filter(s -> s.getUserId().equals(userId) && s.getStatus() != 2).collect(Collectors.toList());
            if (list.size() > 0) {
                throw new YamiShopBindException("受赠方持仓数据异常");
            }
            List<PersonNft> list1 = personNfts.stream().filter(s -> s.getUserId().equals(userId) && s.getStatus() == 2).collect(Collectors.toList());
            if (list1.size() > 0) {
                //如果受赠方已有记录直接修改状态
                PersonNft personNft1 = list1.get(0);
                prodCode.add(personNft1.getDawProductCode());
                personNft1.setStatus(0);
                personNft1.setCreateTime(DateUtil.date());
                personNft1.setSceneType(Integer.valueOf(SceneType.RedAdd.getCode()));
                lsit.add(personNft1);
            } else {
                //受赠方添加持仓 -没有新增一条
                PersonNft personNft1 = personNfts.get(0);
                prodCode.add(personNft1.getDawProductCode());
                PersonNft person = PersonNft.builder()
                        .status(0)
                        .id(IdUtil.getSnowflake().nextIdStr())
                        .createTime(DateUtil.date())
                        .userId(userId)
                        .tokenId(tokenId)
                        .productId(personNftApply.getProductId())
                        .dawProductCode(personNft1.getDawProductCode())
                        .denomId(personNftApply.getDenomId())
//                        .DawNameId(personNftApply.getDawNameId());
                        .chainCode(personNftApply.getChainCode())
                        .channelCode(personNftApply.getChannelCode())
                        .sceneType(Integer.valueOf(SceneType.RedAdd.getCode()))
                        .build();
                lsitAdd.add(person);
            }
            //4 转增方减去持仓
            List<PersonNft> personNfts2 = personNfts.stream().filter(s -> s.getUserId().equals(personNftApply.getUserId()) && s.getStatus() == 1).collect(Collectors.toList());
            if (personNfts2.size() != 1) {
                throw new YamiShopBindException("转赠方持仓数据异常");
            } else {
                //受赠方减去持仓
                PersonNft personNft1 = personNfts2.get(0);
                personNft1.setStatus(2);
                personNft1.setUpdateTime(DateUtil.date());
                personNft1.setSceneType(Integer.valueOf(SceneType.RedTransfer.getCode()));
                lsit.add(personNft1);
            }
            // 权益转移修改
            applicationContext.publishEvent(new UpdateRightsEvent(tokenId, userId, personNftApply.getUserId()));
        }
        if (lsit.size() > 0) {
            personNftService.updateBatchById(lsit);
        }
        if (lsitAdd.size() > 0) {
            personNftService.saveBatch(lsitAdd);
        }
        //2增加受赠方藏品记录
        String idStr = IdUtil.getSnowflake().nextIdStr();
        PersonNftAccount personNftAccount = PersonNftAccount.builder()
                .sceneType(Integer.valueOf(SceneType.RedAdd.getCode()))
                .content(tokenIds)
                .dawProductCode(String.join(",", prodCode))
//                .dawNameId(personNftApply.getDawNameId())
                .denomId(personNftApply.getDenomId())
                .userId(userId)
                .createTime(DateUtil.date())
                .id(idStr)
                .count(tokenList.size())
                .channelType(personNftApply.getChannelType())
                .productId(personNftApply.getProductId())
                .orderId(redPacketId + "")
                .chainCode(personNftApply.getChainCode())
                .channelCode(personNftApply.getChannelCode())
                .build();
        personNftAccountMapper.save(personNftAccount);
        //5 转增方转增记录
        PersonNftAccount personNftAccount1 = PersonNftAccount.builder()
                .sceneType(Integer.valueOf(SceneType.RedTransfer.getCode()))
                .content(tokenIds)
                .dawProductCode(String.join(",", prodCode))
//                .dawNameId(personNftApply.getDawNameId())
                .denomId(personNftApply.getDenomId())
                .userId(personNftApply.getUserId())
                .createTime(DateUtil.date())
                .id(IdUtil.getSnowflake().nextIdStr())
                .count(tokenList.size())
                .productId(personNftApply.getProductId())
                .orderId(redPacketId + "")
                .channelType(personNftApply.getChannelType())
                .chainCode(personNftApply.getChainCode())
                .channelCode(personNftApply.getChannelCode())
                .build();
        personNftAccountMapper.save(personNftAccount1);
        List<AssetTrendsVO> list = new ArrayList<>();
        logger.info("红包领取成功，完成增加持仓=================进入红包记账");
        for (String tokenId : tokenList) {
            AssetTrendsVO trendsVO = AssetTrendsVO.builder().denomId(personNftApply.getDenomId()).tokenId(tokenId)
                    .fromUserId(personNftApply.getUserId()).toUserId(userId).outId(idStr).prodId(personNftApply.getProductId()).build();
            list.add(trendsVO);
        }
        applicationContext.publishEvent(new AssetTrendsEvent(TradeType.RED_ENVELOPE.getValue(), list));
        logger.info("==========红包领取成功，红包记账完成=============");
    }

    private String getTokenByDtc(RedPacketInfo byId, RedPacketRecord redPacketRecord) {
        // 获取 未使用的token
        QueryWrapper<RedTokenRecord> redTokenRecordQueryWrapper = new QueryWrapper<>();
        redTokenRecordQueryWrapper.eq("red_id", byId.getId());
        redTokenRecordQueryWrapper.eq("status", "0");
        redTokenRecordQueryWrapper.last(" limit " + redPacketRecord.getAmount().intValue());
        List<RedTokenRecord> list = redTokenRecordService.list(redTokenRecordQueryWrapper);
        list.forEach(s -> {
            s.setStatus(redPacketRecord.getRecType().toString());
        });
        // 修改查询出 token 的状态
        redTokenRecordService.updateBatchById(list);
        List<String> collect = list.stream().map(RedTokenRecord::getTokensId).collect(Collectors.toList());
        return String.join(",", collect);
    }


}
